package com.xspace.android.imcommon.http;

import android.os.Handler;
import android.util.Log;

import org.xml.sax.SAXException;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import javax.xml.parsers.ParserConfigurationException;

public class ConnectorImpl implements Runnable {

	private String url = null;

	private Thread connectThread = null;

	private NetworkListener listener = null;

	private String params = null;

	private int connectTimeout = 5 * 1000;

	private int readTimeout = 5 * 1000;

	/**
	 * If need native thread to perform View invalidate, we should using handler
	 * */
	private Handler mHandler = null;

	/**
	 * If need to identify callback in parent thread, should set mCommand .
	 * */
	private int mCommand = -1;

	/**
	 * reconnection to remote server when necessary
	 * */
	private boolean bRetry = false;

	private int method = GET;
	public static final int POST = 1;
	public static final int GET = 0;

	private static final String TAG = "ConnectorImpl";

	public ConnectorImpl(String url, String aParams, NetworkListener aListener, int method) {
		this.url = url;
		params = aParams;
		listener = aListener;
		this.method = method;
	}

	public void setNativeHandlerCallBack(Handler handler, int cmd) {
		mHandler = handler;
		mCommand = cmd;
	}

	public void setNetworkListener(NetworkListener aListener) {
		listener = aListener;
	}

	public void connect() {
		if (connectThread == null) {
			connectThread = new Thread(this);
			connectThread.start();
		}
	}

	public void run() {

		if (url == null || url.equals("")) {
			return;
		}

		if (listener == null) {
			return;
		}

		try {
			// int apn = APNMgr.getApnType();
			// if (apn == APNMgr.NOT_EXIST) {
			// listener.action(NetworkListener.APN_NOTEXIST, new Integer(apn));
			// } else {
			connectTimeout = 30 * 1000;
			readTimeout = 50 * 1000;
			if (method == GET) {
				doGet();
			} else if (method == POST) {
				doPost();
			} else {
				Log.e(TAG, "No such method " + method + " excute!");
			}
			// }
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {

		}
	}

	private void doPost() throws IOException {
		StringBuilder builder = new StringBuilder(url);
		String desturl = builder.toString();
		Log.d("cn.wlct.t", "POST URL: " + desturl);
		
		InputStream stream = null;
		HttpURLConnection conn = null;
		try {
			Log.d("cn.wlct.t", "POST: " + params);
			byte[] data = null;
			if (params == null) {
				data = new byte[0];
			} else {
				data = params.getBytes();
			}

			URL url = new URL(desturl);
			conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("POST");
			conn.setConnectTimeout(connectTimeout);
			conn.setReadTimeout(readTimeout);
			conn.setDoOutput(true);
			conn.setDoInput(true);
			conn.setUseCaches(false);
			conn.setRequestProperty("Accept", "text/plain");
			// conn.setRequestProperty("Content-Type",
			// "application/x-www-form-urlencoded");
			conn.setRequestProperty("content-type", "text/html");
			conn.setRequestProperty("Connection", "Close");
			conn.setRequestProperty("Content-Length", String.valueOf(data.length));
			conn.connect();

			OutputStream outputStream = conn.getOutputStream();
			outputStream.write(data);
			outputStream.flush();
			outputStream.close();

			int resp_code = conn.getResponseCode();
			//listener.action(NetworkListener.RESPONSE_CODE, new Integer(resp_code));
			Log.d("cn.wlct.t", "GETRESPONSE:" + resp_code);
			if (resp_code == HttpURLConnection.HTTP_OK) {
				stream = conn.getInputStream();
				if (mCommand != -1)
					listener.action(NetworkListener.RECEIVE_STREAM, new Object[] { new Integer(mCommand), stream });
				else
					listener.action(NetworkListener.RECEIVE_STREAM, stream);
			}else{
				listener.action(NetworkListener.REQUEST_TIMEOUT, null);
			}
		} catch (IOException e) {
			e.printStackTrace();
			listener.action(NetworkListener.REQUEST_TIMEOUT, null);
		} finally {
			if (stream != null)
				stream.close();
			if (conn != null)
				conn.disconnect();
		}
	}

	private void doGet() throws Exception {
		StringBuffer buffer = new StringBuffer(url);
		if (params != null && params.length() > 0) {
			if (!url.endsWith("?")) {
				buffer.append("?");
			}
			buffer.append(params);
		}
		String desturl = buffer.toString().trim();
		desturl = desturl.replace(" ", "%20");
		Log.d("cn.wlct.t", "GET URL: " + desturl);
		InputStream stream = null;
		HttpURLConnection conn = null;
		try {
			URL url = new URL(desturl);
			conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("GET");
			conn.setDoInput(true);
			conn.setConnectTimeout(connectTimeout);
			conn.connect();

			int resp_code = conn.getResponseCode();
			//listener.action(NetworkListener.RESPONSE_CODE, new Integer(resp_code));

			if (resp_code == HttpURLConnection.HTTP_OK) {
				stream = conn.getInputStream();
				if (stream != null) {
					Log.d("cn.wlct.t", "GETRESPONSE:" + resp_code);
				}
				if (mCommand != -1)
					listener.action(NetworkListener.RECEIVE_STREAM, new Object[] { new Integer(mCommand), stream });
				else
					listener.action(NetworkListener.RECEIVE_STREAM, stream);

			} else {
				listener.action(NetworkListener.STREM_EXCEPTION, null);
				throw new Exception("Connection Impl bad response:" + resp_code);
			}

		} catch (IOException e) {
			e.printStackTrace();
			listener.action(NetworkListener.REQUEST_TIMEOUT, null);
		} finally {
			if (stream != null)
				stream.close();

			if (conn != null)
				conn.disconnect();
		}
	}
}
